package com.tomcat.custom;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.view.Surface;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.msd.ocr.idcard.LibraryInitOCR;
import com.thtf.ocr.ui.camera.CameraThreadPool;
import com.thtf.ocr.ui.camera.CameraView;
import com.thtf.ocr.ui.camera.ICameraControl;
import com.thtf.ocr.ui.camera.MaskView;
import com.thtf.ocr.ui.camera.OCRCameraLayout;
import com.thtf.ocr.ui.camera.PermissionCallback;
import com.thtf.ocr.ui.crop.CropView;
import com.thtf.ocr.ui.crop.FrameOverlayView;
import com.tomcat.custom.util.FileUtil;
import com.tomcat.custom.util.MediaPlayerManager;
import com.tomcat.custom.util.ProgressDialogManager;
import com.tomcat.ocr.idcard.R;

import java.io.File;
import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;


public class CustomCardActivity extends Activity implements View.OnClickListener {
    public static final String KEY_OUTPUT_FILE_PATH = "outputFilePath";
    public static final String KEY_CONTENT_TYPE = "contentType";

    public static final String CONTENT_TYPE_ID_CARD_FRONT = "IDCardFront";
    public static final String CONTENT_TYPE_ID_CARD_BACK = "IDCardBack";

    private static final int REQUEST_CODE_PICK_IMAGE = 100;
    private static final int PERMISSIONS_REQUEST_CAMERA = 800;
    private static final int PERMISSIONS_EXTERNAL_STORAGE = 801;
    final ReentrantReadWriteLock nativeModelLock = new ReentrantReadWriteLock();

    private File outputFile;
    private CropView cropView;
    private String bitmapFileDir;
    private ImageView lightButton;
    private CameraView cameraView;
    private ImageView takePhotoBtn;
    private ImageView album_button;
    private ImageView displayImageView;
    private OCRCameraLayout confirmResultContainer;
    private OCRCameraLayout takePictureContainer;
    private CameraView.OnTakePictureCallback takePictureCallback;
    private CameraView.OnTakePictureCallback autoTakePictureCallback;

    @SuppressLint("HandlerLeak")
    private Handler ocrHandler;
    private Handler uiHandler = new Handler();
    private PermissionCallback permissionCallback = new PermissionCallback() {
        @Override
        public boolean onRequestPermission() {
            ActivityCompat.requestPermissions(CustomCardActivity.this,
                    new String[]{Manifest.permission.CAMERA},
                    PERMISSIONS_REQUEST_CAMERA);
            return false;
        }
    };
    private MediaPlayerManager mediaPlayerManager;
    private ProgressDialogManager progressDialogManager;
    private OCRCameraLayout cropContainer;
    private FrameOverlayView overlayView;
    private MaskView cropMaskView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.bd_ocr_activity_camera);
        initView();
        initParams();
        callBackManager();
        LibraryInitOCR.initDecode(this, ocrHandler, true);
        cameraView.setAutoPictureCallback(autoTakePictureCallback);
    }

    private void initView() {
        confirmResultContainer = (OCRCameraLayout) findViewById(R.id.confirm_result_container);
        takePictureContainer = (OCRCameraLayout) findViewById(R.id.take_picture_container);

        cropView = (CropView) findViewById(R.id.crop_view);
        album_button = (ImageView) findViewById(R.id.album_button);
        cameraView = (CameraView) findViewById(R.id.camera_view);
        lightButton = (ImageView) findViewById(R.id.light_button);
        takePhotoBtn = (ImageView) findViewById(R.id.take_photo_button);
        displayImageView = (ImageView) findViewById(R.id.display_image_view);


        cropView = (CropView) findViewById(R.id.crop_view);
        cropContainer = (OCRCameraLayout) findViewById(R.id.crop_container);
        overlayView = (FrameOverlayView) findViewById(R.id.overlay_view);
        cropMaskView = (MaskView) cropContainer.findViewById(R.id.crop_mask_view);

        lightButton.setOnClickListener(this);
        takePhotoBtn.setOnClickListener(this);
        album_button.setOnClickListener(this);

        cameraView.getCameraControl().setPermissionCallback(permissionCallback);
    }

    private void initParams() {
        setOrientation(getResources().getConfiguration());
        String outputPath = getIntent().getStringExtra(KEY_OUTPUT_FILE_PATH);
        //正反面参数类型
        String contentType = getIntent().getStringExtra(KEY_CONTENT_TYPE);
        if (contentType == null) {
            contentType = CONTENT_TYPE_ID_CARD_FRONT;
        }
        if (outputPath != null) {
            outputFile = new File(outputPath);
        }
        int maskType = MaskView.MASK_TYPE_ID_CARD_FRONT;
        switch (contentType) {
            case CONTENT_TYPE_ID_CARD_FRONT:
                maskType = MaskView.MASK_TYPE_ID_CARD_FRONT;
                break;
            case CONTENT_TYPE_ID_CARD_BACK:
                maskType = MaskView.MASK_TYPE_ID_CARD_BACK;
                break;
        }


        outputFile = new File(FileUtil.getSaveFile(getApplication()).getAbsolutePath());
        cameraView.setEnableScan(true);
        cameraView.setMaskType(maskType, this);
        cropMaskView.setMaskType(maskType);
        mediaPlayerManager = new MediaPlayerManager(this, R.raw.shout);
        progressDialogManager = new ProgressDialogManager(this);
    }

    private void callBackManager() {
        ocrHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                Random random = new Random();
                int randomInt = random.nextInt(7);
                switch (msg.what) {
                    //解码成功
                    case LibraryInitOCR.DECODE_SUCCESS:
                        cameraView.RESULT_STATUS = cameraView.SCAN_SUCCESS;
                        Intent intent = (Intent) msg.obj;
                        setResult(RESULT_OK, intent);
                        progressDialogManager.cancelProgressDialog();
                        finish();
                        break;
                    //解码失败
                    case LibraryInitOCR.DECODE_FAIL:
                        progressDialogManager.cancelProgressDialog();
                        cameraView.RESULT_STATUS = randomInt + 1;
                        break;

                    //提示重新聚焦
                    case LibraryInitOCR.DECODE_AUTO_FOCUS:
                        cameraView.RESULT_STATUS = randomInt + 1;
                        progressDialogManager.cancelProgressDialog();
                        break;
                    default:
                        cameraView.RESULT_STATUS = randomInt + 1;
                        progressDialogManager.cancelProgressDialog();
                        break;
                }
                cameraView.status = cameraView.SCAN_FREE;
            }
        };
        takePictureCallback = new CameraView.OnTakePictureCallback() {
            @Override
            public void onPictureTaken(final Bitmap bitmap) {
                cropView.setBitmap(bitmap);
                showPicture(bitmap);
                showCrop();
                LibraryInitOCR.decode(FileUtil.saveBitmap(cropView.getBitmap()));
            }
        };
        autoTakePictureCallback = new CameraView.OnTakePictureCallback() {
            @Override
            public void onPictureTaken(final Bitmap bitmap) {
                try {
                    nativeModelLock.readLock().lock();
                    if (cameraView.RESULT_STATUS != cameraView.SCAN_SUCCESS) {
                        cropView.setBitmap(bitmap);
                        LibraryInitOCR.decode(FileUtil.saveBitmap(cropView.getBitmap()));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    nativeModelLock.readLock().unlock();
                }
            }
        };
    }


    private void showPicture(final Bitmap bitmap) {
        uiHandler.post(new Runnable() {
            @Override
            public void run() {
                displayImageView.setImageBitmap(bitmap);
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.album_button:
                cameraView.ORC_TYPE = cameraView.ALBUM_ORC;
                openAlbum();
                break;
            case R.id.take_photo_button:
                cameraView.ORC_TYPE = cameraView.SHOUT_ORC;
                mediaPlayerManager.playerMedia();
                progressDialogManager.buildProgressDialog();
                cameraView.takePicture(outputFile, takePictureCallback);
                break;
            case R.id.light_button:
                if (cameraView.getCameraControl().getFlashMode() == ICameraControl.FLASH_MODE_OFF) {
                    cameraView.getCameraControl().setFlashMode(ICameraControl.FLASH_MODE_TORCH);
                } else {
                    cameraView.getCameraControl().setFlashMode(ICameraControl.FLASH_MODE_OFF);
                }
                break;
        }
    }

    private void openAlbum() {
        if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                ActivityCompat.requestPermissions(CustomCardActivity.this,
                        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                        PERMISSIONS_EXTERNAL_STORAGE);
                return;
            }
        }
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setOrientation(newConfig);
    }

    private void setOrientation(Configuration newConfig) {
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        int orientation;
        int cameraViewOrientation = CameraView.ORIENTATION_PORTRAIT;
        switch (newConfig.orientation) {
            case Configuration.ORIENTATION_PORTRAIT:
                cameraViewOrientation = CameraView.ORIENTATION_PORTRAIT;
                orientation = OCRCameraLayout.ORIENTATION_PORTRAIT;
                break;
            case Configuration.ORIENTATION_LANDSCAPE:
                orientation = OCRCameraLayout.ORIENTATION_HORIZONTAL;
                if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
                    cameraViewOrientation = CameraView.ORIENTATION_HORIZONTAL;
                } else {
                    cameraViewOrientation = CameraView.ORIENTATION_INVERT;
                }
                break;
            default:
                orientation = OCRCameraLayout.ORIENTATION_PORTRAIT;
                cameraView.setOrientation(CameraView.ORIENTATION_PORTRAIT);
                break;
        }
        takePictureContainer.setOrientation(orientation);
        cameraView.setOrientation(cameraViewOrientation);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_PICK_IMAGE) {
            cameraView.ORC_TYPE = cameraView.ALBUM_ORC;
            if (resultCode == Activity.RESULT_OK) {
                mediaPlayerManager.albumMedia();
                Uri uri = data.getData();
                bitmapFileDir = FileUtil.getRealPathFromURI(this, uri);
                cropView.setFilePath(bitmapFileDir);
                showPicture(cropView.getBitmap());
                cameraView.ORC_TYPE = cameraView.ALBUM_ORC;
                CameraThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        LibraryInitOCR.decode(bitmapFileDir);
                    }
                });
                showCrop();
                progressDialogManager.buildProgressDialog();
            } else {
                cameraView.getCameraControl().resume();
            }
        }
    }

    private void showCrop() {
        cameraView.getCameraControl().pause();
        takePictureContainer.setVisibility(View.INVISIBLE);
        confirmResultContainer.setVisibility(View.INVISIBLE);
        cropContainer.setVisibility(View.VISIBLE);
    }

    /***
     * 权限申请控制
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case PERMISSIONS_REQUEST_CAMERA: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    cameraView.getCameraControl().refreshPermission();
                } else {
                    Toast.makeText(getApplicationContext(), R.string.camera_permission_required, Toast.LENGTH_LONG).show();
                }
                break;
            }
            case PERMISSIONS_EXTERNAL_STORAGE:
            default:
                break;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        cameraView.stop();
    }

    @Override
    protected void onResume() {
        super.onResume();
        cameraView.start();
        cameraView.RESULT_STATUS = -1;
        cameraView.status = -1;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        CameraThreadPool.cancelAutoFocusTimer();
        ocrHandler.removeCallbacksAndMessages(null);
        mediaPlayerManager.stopMedia();
        FileUtil.cleanDirectory(FileUtil.initPath());
        //LibraryInitOCR.closeDecode();
    }


}
